package cn.silver.module.system.service.impl;

import cn.silver.framework.mybatis.bean.PageModel;
import cn.silver.framework.mybatis.service.impl.BaseServiceImpl;
import cn.silver.framework.openapi.model.ResultPage;
import cn.silver.module.authority.domain.SysRole;
import cn.silver.module.authority.bean.RoleBean;
import cn.silver.module.authority.service.ISysRoleService;
import cn.silver.module.system.bean.UserBean;
import cn.silver.module.system.bean.UserRoleBean;
import cn.silver.module.system.domain.SysUser;
import cn.silver.module.system.domain.SysUserRole;
import cn.silver.module.system.enums.UserStatusEnums;
import cn.silver.module.system.mapper.SysUserRoleMapper;
import cn.silver.module.system.param.UserParam;
import cn.silver.module.system.param.UserRoleParam;
import cn.silver.module.system.service.ISysUserRoleService;
import cn.silver.module.system.service.ISysUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author zhouxiaobo
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SysUserRoleServiceImpl extends BaseServiceImpl<SysUserRoleMapper, SysUserRole, UserRoleParam, UserRoleBean> implements ISysUserRoleService {

    @Lazy
    @Resource
    private ISysRoleService roleService;
    @Lazy
    @Resource
    private ISysUserService userService;

    @Override
    public void init() {
        String userId = this.userService.init();
        String roleId = this.roleService.init();
        List<SysUserRole> exists = this.baseMapper.selectList(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId).eq(SysUserRole::getRoleId, roleId));
        if (CollectionUtils.isEmpty(exists)) {
            SysUserRole entity = new SysUserRole(userId, roleId);
            entity.preInsert();
            this.baseMapper.insert(entity);
        }
    }

    @Override
    public ResultPage<UserRoleBean> selectPage(PageModel page, UserRoleParam filter) {
        ResultPage<UserRoleBean> result = super.selectPage(page, filter);
        if (result.getTotal() > 0) {
            List<UserBean> users = this.userService.selectByIds(result.getRows().stream().map(UserRoleBean::getUserId).toList());
            Map<String, UserBean> userMap = users.stream().collect(Collectors.toMap(UserBean::getId, Function.identity()));
            List<RoleBean> roles = this.roleService.selectByIds(result.getRows().stream().map(UserRoleBean::getRoleId).toList());
            Map<String, RoleBean> roleMap = roles.stream().collect(Collectors.toMap(RoleBean::getId, Function.identity()));
            result.getRows().stream().forEach(item -> {
                item.setRole(roleMap.get(item.getRoleId()));
                item.setUser(userMap.get(item.getUserId()));
            });
        }
        return result;
    }

    @Override
    public List<RoleBean> selectRoleGroup(String userId) {
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.exists("select 1 from sys_user_role u where u.user_id = {0}", userId);
        return roleService.selectList(queryWrapper);
    }

    /**
     * 根据条件分页查询已分配用户角色列表
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */
    @Override
    public ResultPage<UserBean> selectAllocatedList(String roleId, UserParam user, PageModel pageModel) {
        LambdaQueryWrapper<SysUser> wrapper = Wrappers.lambdaQuery();
        wrapper.like(StringUtils.isNotBlank(user.getCode()), SysUser::getCode, user.getCode())
                .like(StringUtils.isNotBlank(user.getName()), SysUser::getName, user.getName())
                .like(StringUtils.isNotBlank(user.getMobile()), SysUser::getMobile, user.getMobile())
                .like(StringUtils.isNotBlank(user.getCode()), SysUser::getCode, user.getCode())
                .eq(SysUser::getStatus, UserStatusEnums.NORMAL.getCode())
                .exists("select 1 from sys_user_role u where u.role_id = {0}", roleId)
                .orderByAsc(SysUser::getCreateTime);
        return userService.selectPage(pageModel, wrapper);
    }

    /**
     * 根据条件分页查询未分配用户角色列表
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */
    @Override
    public ResultPage<UserBean> selectUnallocatedList(String roleId, UserParam user, PageModel pageModel) {
        LambdaQueryWrapper<SysUser> wrapper = Wrappers.lambdaQuery();
        wrapper.like(StringUtils.isNotBlank(user.getCode()), SysUser::getCode, user.getCode())
                .like(StringUtils.isNotBlank(user.getName()), SysUser::getName, user.getName())
                .eq(StringUtils.isNotBlank(user.getType()), SysUser::getType, user.getType())
                .eq(StringUtils.isNotBlank(user.getStatus()), SysUser::getStatus, user.getStatus())
                .like(StringUtils.isNotBlank(user.getMobile()), SysUser::getMobile, user.getMobile())
                .like(StringUtils.isNotBlank(user.getEmail()), SysUser::getEmail, user.getEmail())
                .eq(SysUser::getStatus, UserStatusEnums.NORMAL.getCode())
                .notExists(StringUtils.isNotBlank(roleId), "select 1 from sys_user_role u where u.role_id = {0}", roleId)
                .orderByAsc(SysUser::getCreateTime);
        return userService.selectPage(pageModel, wrapper);
    }

    @Override
    public QueryWrapper<SysUserRole> buildQueryWrapper(UserRoleParam param) {
        QueryWrapper<SysUserRole> wrapper = Wrappers.query();
        wrapper.eq(StringUtils.isNotBlank(param.getUserId()), "user_id", param.getUserId());
        wrapper.eq(StringUtils.isNotBlank(param.getRoleId()), "role_id", param.getRoleId());
        StringBuilder userBilder = new StringBuilder("select 1 from sys_user u where u.id = sys_user_role.user_id ");
        if (StringUtils.isNotBlank(param.getUserCode())) {
            userBilder.append("and u.code like '%").append(param.getUserCode()).append("%'");
        }
        if (StringUtils.isNotBlank(param.getUserName())) {
            userBilder.append("and u.name like '%").append(param.getUserName()).append("%'");
        }
        if (StringUtils.isNotBlank(param.getUserType())) {
            userBilder.append("and u.type = '").append(param.getUserType()).append("'");
        }
        if (StringUtils.isNotBlank(param.getUserStatus())) {
            userBilder.append("and u.status = '").append(param.getUserStatus()).append("'");
        }
        wrapper.exists(userBilder.toString());
        StringBuilder builder = new StringBuilder("select 1 from sys_role r where r.id = sys_user_role.role_id ");
        if (StringUtils.isNotBlank(param.getRoleCode())) {
            builder.append("and r.code like '%").append(param.getRoleCode()).append("%'");
        }
        if (StringUtils.isNotBlank(param.getRoleName())) {
            builder.append("and r.name like '%").append(param.getRoleName()).append("%'");
        }
        if (StringUtils.isNotBlank(param.getRoleType())) {
            builder.append("and r.type = '").append(param.getRoleType()).append("'");
        }
        if (StringUtils.isNotBlank(param.getRoleStatus())) {
            builder.append("and r.status = '").append(param.getRoleStatus()).append("'");
        }
        if (StringUtils.isNotBlank(param.getRoleScope())) {
            builder.append("and r.scope = '").append(param.getRoleScope()).append("'");
        }
        wrapper.exists(builder.toString());
        return wrapper;
    }
}
